#define _GNU_SOURCE
#include  "daemon_process.h"
#include  "log/log.h"
#include  <stdlib.h>
#include  <string.h>
#include <sys/wait.h>
#include  <sys/reboot.h>
#include  <unistd.h>
#include <signal.h>



SubProcess  *daemon_process_initSubProcess(char  *subProcessName)
{
    //初始化结构体
   SubProcess *subProcess=  malloc(sizeof(SubProcess));
   if(subProcess==NULL)
   {
      log_error("malloc subProcess failed");
      goto SUB_PROCESS_FAILED;
   }
    //填值
   subProcess->cmd = PROCESS_CMD;
   subProcess->args=malloc(sizeof(char *)*3);
   if(subProcess->args==NULL)
   {
      log_error("malloc subProcess args failed");
      goto SUB_PROCESS_ARGS_FAILED;
   }

   subProcess->args[0]=PROCESS_CMD ;

   // subProcess->args[1]= subProcessName;
   subProcess->args[1]=malloc(strlen(subProcessName)+1);
   if(subProcess->args[1]==NULL)
   {
      log_error("malloc subProcess args[1] failed");
      goto SUB_PROCESS_ARG1_FAILED;
   }
   strcpy(subProcess->args[1],subProcessName);
   
   subProcess->args[2]= NULL;

   subProcess->pid= -1;
   subProcess->fail_times=0;

SUB_PROCESS_ARG1_FAILED:
   free(subProcess->args[1]);
SUB_PROCESS_ARGS_FAILED:
   free(subProcess->args);
SUB_PROCESS_FAILED:
   free(subProcess);

   return subProcess;

}

//2 启动子进程
int daemon_process_startSubProcess(SubProcess *subProcess)
{   int status=0;
    //1 依据pid 判断子进程是否已经启动
    if(subProcess->pid > 0&& waitpid(subProcess->pid,&status,WNOHANG)==0)  //WNOHANG 是非阻塞状态，获得当前状态 0是正常状态 1是异常状态
    {   //子进程正常
        return 0;
    }
    if(status!=0) // 不等于0 表示子进程异常退出
    {  //异常状态则尝试重启
        log_info("sub process %s exit,restart it",subProcess->args[1]);
        subProcess->fail_times++ ;
         
        if(subProcess->fail_times >MAX_FAIL_TIMES)
        {
            // 子进程重启失败
            log_error("sub process %s restart failed",subProcess->args[1]);
            reboot(RB_AUTOBOOT);
        }
     }

        // 启动子进程
        subProcess->pid=fork();
        if(subProcess->pid==0)// 子进程
        {
            execve(subProcess->args[0],subProcess->args,__environ); // 必须声明  unistd
            log_error("execv %s failed",subProcess->args[0]);
            exit(1);
        }else if(subProcess->pid>0){// 父进程
            log_info("sub process %s start success",subProcess->args[1]);
            return 0;
        }else{
            log_error("fork %s failed",subProcess->args[0]);
            return -1;
        }
    }

}
//3 停止子进程
int daemon_process_stopSubProcess(SubProcess *subProcess)
{
    if(kill(subProcess->pid,SIGTERM)==0)  //必须 define _GNU_SOURCE
    { 
         waitpid(subProcess->pid,NULL,0);
         log_info("kill %s success",subProcess->args[1]);
         return 0;
    }
    else
    {
         log_error("kill %s failed",subProcess->args[1]);
         return -1;
    }
}



 